/*********************************************************
*Copyright (c) 2009 Rob Groves. All Rights in Pw 
*@des: Mysql数据集 简单封装处理
*@name: QueryResult.cpp
*@author: zhognsx
*@time: 2015-02-05
*********************************************************/

#include "QueryResult.h"
#include "DbQuery.h"

    
QueryResult::QueryResult() 
{

}

QueryResult::~QueryResult()
{

}

void QueryResult::init()
{
    vecData.clear();
}

int QueryResult::SetRes(MYSQL_RES *result)
{   
    uint32_t unRecords = mysql_num_rows(result);
    if (0 == unRecords){
        return 0;
    }

    uint32_t num_fields = mysql_num_fields(result);
    
    MYSQL_FIELD *fields = NULL;
    fields = mysql_fetch_fields(result);
    if (!fields){
        //MYSQL_WAR_ERROR("Error mysql_fetch_fields fail");
        mysql_free_result( result );
        return EMYSQLErrSys;
    }

    unsigned long *lengths = NULL;
    MYSQL_ROW row;
    for(uint32_t unIndex = 0; unIndex < unRecords; unIndex++)
    {
        row = mysql_fetch_row(result);
        lengths = mysql_fetch_lengths(result);
        if (!lengths){
            //MYSQL_WAR_ERROR("Error mysql_fetch_lengths fail,index", unIndex);
            mysql_free_result( result );
            return EMYSQLErrSys;
        }

        std::map<string, MYSQLValue> tmpMapData;
        for(uint32_t i = 0; i < num_fields; i++)
        {
            MYSQLValue &value = tmpMapData[fields[i].name];
            value.SetData((char*)row[i], lengths[i]);
        }
        vecData.push_back(tmpMapData);
    }

    mysql_free_result( result );

    return EMYSQLSuc;
}

int QueryResult::getRowCount()
{
    return vecData.size();
}

int QueryResult::getColumnCount()
{
    if (vecData.size() == 0){
        return 0;
    }
    std::map<string, MYSQLValue>& tmpRow = vecData[0];
    return tmpRow.size();
}

string QueryResult::getElement(int row, string key)
{
    if (vecData.size() < row){
        return "";
    }

    std::map<string, MYSQLValue>& tmpRow = vecData[row];
	
	std::map<string, MYSQLValue>::iterator itr;
	itr = tmpRow.find(key); 
	if ( itr == tmpRow.end() ){
		return "";
	}

	if (itr->second.data() == NULL){
		return "";
	}
	return itr->second.data();
}

void QueryResult::PushBack(std::map<string, MYSQLValue>& row)
{
	vecData.push_back(row);
}

bool QueryResult::SelectValue(std::map<string, MYSQLValue>& row, string key, string value)
{
	std::map<string, MYSQLValue>::iterator itr = row.find(key);
	//没有参数
	if (itr == row.end()){
		return false;
	}

	return (itr->second.data() == value);
}

QueryResult QueryResult::Select(string key1, string key2, string key3, string value1, string value2, string value3)
{
	QueryResult ret;
	int row = vecData.size();
	if (key1 == "")
	{
		return ret;
	}
	//只有第一个 key有效
	else if (key2 == "") 
	{ 
		for (int i = 0; i < row; i++ ){
			std::map<string, MYSQLValue>& row = vecData[i];
			if (SelectValue(row, key1, value1)){
				ret.PushBack(row);
			}
		}
	}
	//只有前两个 key有效
	else if (key3 == "") 
	{ 
		for (int i = 0; i < row; i++ ){
			std::map<string, MYSQLValue>& row = vecData[i];
			if (SelectValue(row, key1, value1) && SelectValue(row, key2, value2)){
				ret.PushBack(row);
			}
		}
	}
	//三个Key 都有效
	else  
	{ 
		for (int i = 0; i < row; i++ ){
			std::map<string, MYSQLValue>& row = vecData[i];
			if (SelectValue(row, key1, value1) && SelectValue(row, key2, value2) 
				&& SelectValue(row, key3, value3) )
			{
				ret.PushBack(row);
			}
		}
	}
	return ret;
}

/////////////////////////////////////////////////////////////////////
MYSQLValue::MYSQLValue()
{
    m_bNull = true;
}

MYSQLValue::~MYSQLValue() 
{

}

//设置Data
int MYSQLValue::SetData(const char* pData, int iLen)
{
    if (!pData)
    {
        m_bNull = true;
        return 0;
    }

    m_bNull = false;

    m_strData.resize(iLen+1);
    memcpy((char*)m_strData.data(), pData, iLen);
    ((char*)m_strData.data())[iLen] = '\0';

    return 0;
}

int MYSQLValue::size()
{
    if (m_bNull)
    {
        return -1;
    }
    return m_strData.size() - 1;
}

const char* MYSQLValue::data()
{
    if (m_bNull)
    {
        return NULL;
    }
    return m_strData.data();
}

int MYSQLValue::pri_as(char *& val)
{
    val = (char*)data();
    return 0;
}
int MYSQLValue::pri_as(const char *& val)
{
    val = data();
    return 0;
}

int MYSQLValue::pri_as(char& val)
{
    int32_t tmp_val;
    int ret = pri_as(tmp_val);
    val = tmp_val;
    return ret;
}

int MYSQLValue::pri_as(unsigned char& val)
{
    uint32_t tmp_val;
    int ret = pri_as(tmp_val);
    val = tmp_val;
    return ret;
}

int MYSQLValue::pri_as(string& val)
{
    if (m_bNull)
    {
        val = "";
    }
    val = m_strData.data();
    return 0;
}
